package com.ajl.wx.module.websocket;

import com.ajl.wx.beans.po.WechatUserPO;
import com.ajl.wx.utils.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;


public  class WebSocketManager implements IWebSocket {
    private Logger logger = LoggerFactory.getLogger(WebSocketManager.class);

    private static WebSocketManager webSocketManager;

    public static synchronized WebSocketManager getInstance() {
        if (webSocketManager==null){
            webSocketManager =new WebSocketManager();
        }
        return webSocketManager;
    }
    public WebSocketManager() {

    }

    /**
     * 保存WebSocket,key 是openId，value是Session
     */
    private ConcurrentHashMap<String, Session> concurrentMap = new ConcurrentHashMap<>();

    /**
     * 离线消息
     */
    private LinkedList< Map<String,Object>> offlineMessage =new LinkedList< Map<String,Object>>(){
        @Override
        public boolean add( Map<String,Object> s) {
            if (offlineMessage.size()>150){
                offlineMessage.pop();
            }
            return super.add(s);
        }
    };


    @Override
    public void addUser(String id, Session session) {
        logger.info("客户端连接{}",id);
            try {
                if (concurrentMap.containsKey(id)) {
                    concurrentMap.get(id).close();
                }
                concurrentMap.put(id,session);
            } catch (IOException e) {
                e.printStackTrace();
            }

    }

    @Override
    public void remove(String id) {
        concurrentMap.remove(id);
        logger.info("客户端断开{}",id);
    }

    @Override
    public boolean isOnline(String openId) {
        return concurrentMap.containsKey(openId);
    }


    @Override
    public void broadcastMessage(WechatUserPO user, String msg) {
        if(StringUtils.isNull(msg)){return;}
        /**
         * 构建WebSocketMessageEntity，并广播
         */
        Map<String,Object> map =new HashMap<>();
        map.put("user",user);
        map.put("msg",msg);

        try {
            String body =new ObjectMapper().writeValueAsString(map);
            logger.info("广播{}",body);
            synchronized (offlineMessage){
                offlineMessage.add(map);
            }
            concurrentMap.values().stream().forEach(new Consumer<Session>() {
                @Override
                public void accept(Session session) {
                    try {

                        session.getBasicRemote().sendText(body);
                    }catch (IOException e){

                    }
                }
            });

        }catch (JsonProcessingException j){

        }
    }

    @Override
    public List<Session> listSocketSession() {
        Collection<Session> values = concurrentMap.values();
        return  new ArrayList<>(values);
    }

    @Override
    public List<String> listSessionId() {
        Enumeration<String> keys = concurrentMap.keys();
        List<String> result = new ArrayList<>();
        while (keys.hasMoreElements()) {
            result.add(keys.nextElement() + "");
        }
        return result;
    }

    @Override
    public LinkedList< Map<String,Object>> listOffline() {
        return this.offlineMessage;
    }
}
